#include "rw_lock.hpp"
#include <cassert>
#ifdef _WIN32
    #include <windows.h>
#endif // _WIN32

RWLock g_rw_lock;
int64_t* int_ptr = nullptr;
int64_t sum = 0;
int sign = 0;

void Creat()
{
    for (int times = 0; times < 2000000; times++)
    {
        g_rw_lock.WriteLock();
        sum++;
        sign = 1;
        if (nullptr == int_ptr)
        {
            assert(nullptr == int_ptr);
            int_ptr = new int64_t(0);
        }
        assert(nullptr != int_ptr);
        assert(sign == 1);
        g_rw_lock.WriteUnlock();
    }
}

void Del()
{
    for (int times = 0; times < 2000000; times++)
    {
        g_rw_lock.WriteLock();
        sum++;
        sign = 2;
        if (nullptr != int_ptr)
        {
            assert(nullptr != int_ptr);
            delete int_ptr;
            int_ptr = nullptr;
        }
        assert(nullptr == int_ptr);
        assert(sign == 2);
        g_rw_lock.WriteUnlock();
    }
}

void Read()
{
    for (int times = 0; times < 2000000; times++)
    {
        g_rw_lock.ReadLock();
        sign = 3;
        if (nullptr != int_ptr)
        {
            *int_ptr = *int_ptr + 1;
            assert(nullptr != int_ptr);
        }
        assert(sign == 3);
        g_rw_lock.ReadUnlock();
    }
}

void Test()
{
    std::thread creat_thread;
    std::thread del_thread;
    std::thread read_thread;
    creat_thread = std::thread(Creat);
    del_thread = std::thread(Del);
    read_thread = std::thread(Read);
    creat_thread.join();
    del_thread.join();
    read_thread.join();
    assert(sum == 2000000 * 2);
}

int main()
{
#ifdef _WIN32
    SetConsoleCP(65001);
    SetConsoleOutputCP(65001);
#endif // _WIN32
    Test();
}